#![allow(non_snake_case)]
#![allow(unused)]

use c2rust003::code2prompt::codes2prompts;
use c2rust003::{
    chat,
    chat_c2rust,
    chatgml::C2RustGLM,
    BigModel,
    TranscodeParams,
    TranscodePathParams,
};
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::Read;
#[allow(unused_imports)]
use std::io::{self, Write};
#[allow(unused_imports)]
use std::path::Path;
use std::process::Command;

pub mod parse_tree;

#[derive(Serialize, Deserialize, Debug)]
pub struct TranspileFile {
    pub filename: String,
    pub content: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CodeFile {
    pub filename: String,
    pub content: String,
    pub test: Option<String>,
}

pub fn remove_markdown_code_block(text: &str) -> String {
    // 创建正则表达式来匹配代码块标记
    let re = Regex::new(r"^.*```rust").unwrap();

    let text_b = re.captures(text).map_or(" ", |cap| cap.get(0).map_or(" ", |m| m.as_str())); // re.replace_all(text, "");

    let text_before = text_b.to_string().split("\n").map(|c| {
        if c.starts_with("//") || c.starts_with("/*") || c.starts_with("*/") || c == "\n" {
            c.to_string()
        } else {
            format!("// {}", c)
        }
    }).collect::<Vec<String>>().join("\n");

    let rust_reg = Regex::new(r"```rust").unwrap();
    let mut text_before = rust_reg.replace_all(&text_before, "").to_string();
    let text = re.replace_all(text, "").to_string();
    let _text = text_before.push_str(&text);
    let re = Regex::new(r"```[\s\S]*").unwrap();
    let text_after = re.captures(&text).map_or(" ".to_string(), |cap| cap.get(1).map_or(" ".to_string(), |m| m.as_str().to_string()));
    if text_after.is_empty() {
        return text_before.to_string();
    }
    // println!("第二次匹配的内容:{}", text_after);
    let mut text_before = re.replace_all(&text_before, "").to_string();
    let text_after = text_after.split("\n").map(|c| {
        if c.starts_with("//") || c.starts_with("/*") || c.starts_with("*/") || c == "\n" {
            c.to_string()
        } else {
            format!("// {}", c)
        }
    }).collect::<Vec<String>>().join("\n");
    let r_reg = Regex::new(r"```").unwrap();
    let text_after = r_reg.replace_all(&text_after, " ").to_string();
    let _text = text_before.push_str(&text_after);
    text_before.to_string()
}

pub async fn generate_rust_project(
    name: String,
    c_2_rust_glm: &mut C2RustGLM,
    prompt: CodeFile,
    model: BigModel,
) {
    let src_dir = format!("./Output/{}", name.clone());
    let directory = src_dir.clone();
    let directory_clone = directory.clone();
    let src_d = format!("./Output/{}/src", name.clone());
    let src_str = src_d.clone();
    let prompt_clone = prompt.clone();
    // 判断目录是否存在，没有话创建
    if !Path::new(&directory).exists() {
        fs::create_dir_all(&directory).expect("Failed to create directory");
        fs::create_dir_all(&src_str).expect("Failed to create directory");
    }

    let mut toml =
        File::create(format!("{}/{}", &directory, "Cargo.toml")).expect("Failed to create file");
    let toml_str = format!(
        r#"
[package]
name="{}"
version = "0.0.1"
edition = "2021"

[dependencies]

# [[test]]
# name = "tests"
# path = "src/tests.rs"
    "#,
        name
    );
    toml.write_all(toml_str.as_bytes())
        .expect("Failed to write to file");
    let filename = name.clone() + ".rs"; // "main.rs"; // 
    let mut file =
        File::create(format!("{}/src/{}", &directory, filename)).expect("Failed to create file");
    let mut test =
        File::create(format!("{}/src/{}", &directory, "main.rs")).expect("Failed to create file");
    let mut c_2_r_glm = c_2_rust_glm.clone();
    let _result = chat(&prompt_clone.content, Some(c_2_rust_glm), model.clone(), name.clone()).await;
    // 开启一个新线程执行cargo check 并将返回的结果重新执行chat函数，最多执行3次
    let mut c_2_rust_glm = c_2_rust_glm.clone();
    let name_clone = name.clone();
    
    let result = tokio::spawn(async move {
        let mut attempt = 0;
        let max_attempts = 3;
        let mut final_result = _result.clone();
        while attempt < max_attempts {
            println!("function 开始执行cargo check ... 尝试次数: {}", attempt + 1);
            let mut command = Command::new("cargo")
                .arg("check")
                .current_dir(&directory)
                .spawn()
                .expect("Failed to execute cargo check");
            let mut buf = String::new();
            let stdout = command.stdout.as_mut();
            if let Some(stdout) = stdout {
                if let Ok(_) = stdout.read_to_string(&mut buf) {
                    println!("cargo check 执行完毕: {}", buf);
                }
            }
            if !buf.contains("error") {
                final_result = _result.clone();
                break;
            }
            let p = format!("{}{}", &prompt_clone.content, "\n请根据cargo check的输出，优化代码, 请不要输出cargo check的输出， 以下是cargo check的输出：".to_string() + &buf);
            final_result = chat(&p, Some(&mut c_2_rust_glm), model.clone(), name_clone.clone()).await;
            attempt += 1;
        }
        final_result
        // println!("function 开始执行cargo check ...");
        // let mut command = Command::new("cargo")
        //     .arg("check")
        //     .current_dir(&directory)
        //     .spawn()
        //     .expect("Failed to execute cargo check");
        // let mut buf = String::new();
        // let stdout = command
        //     .stdout
        //     .as_mut();
        // if let Some(stdout) = stdout {
        //     if let Ok(r) = stdout.read_to_string(&mut buf) {
        //         println!("cargo check 执行完毕: {}", buf);
        //     }
        // }
        // let p = format!("{}{}", &prompt_clone.content, "\n请根据cargo check的输出，优化代码, 请不要输出cargo check的输出， 以下是cargo check的输出：".to_string() + &buf);
        // let result = chat(&p, Some(&mut c_2_rust_glm), model.clone(), name_clone.clone()).await;
        // result
    })
    .await
    .unwrap();
    file.write_all(remove_markdown_code_block(&result).as_bytes())
        .expect("Failed to write to file");
    let prompt_test_clone = prompt.clone();
    if let Some(t) = &prompt_test_clone.test {
        let text_prompt_input = prompt_test_clone.test.clone().unwrap(); 
        let test_result = chat(t, Some(&mut c_2_r_glm), model.clone(), name.clone()).await;
        // 与上述代码类似，开启一个新线程执行cargo test 并将返回的结果重新执行chat函数，最多执行3次
        let mut c_2_rust_glm = c_2_r_glm.clone();
        let name_clone = name.clone();
        let test_result = tokio::spawn(async move {
            let mut attempt = 0;
            let max_attempts = 3;
            let mut final_result = test_result.clone();
            while attempt < max_attempts {
                println!("main 开始执行cargo test ... 尝试次数: {}", attempt + 1);
                let mut command = Command::new("cargo")
                    .arg("test")
                    .current_dir(&directory_clone)
                    .spawn()
                    .expect("Failed to execute cargo test");
                let mut buf = String::new();
                let stdout = command.stdout.as_mut();
                if let Some(stdout) = stdout {
                    if let Ok(_) = stdout.read_to_string(&mut buf) {
                        println!("cargo test 执行完毕: {}", buf);
                    }
                }
                if !buf.contains("error") {
                    final_result = test_result.clone();
                    break;
                }
                let p = format!("{}{}", &text_prompt_input, "\n请根据cargo test的输出，优化代码, 请不要输出cargo test的输出， 以下是cargo test的输出：".to_string() + &buf);
                final_result = chat(&p, Some(&mut c_2_rust_glm), model.clone(), name_clone.clone()).await;
                attempt += 1;
            }
            final_result
            // println!("main 开始执行cargo test ...");
            // let mut command = Command::new("cargo")
            //     .arg("test")
            //     .current_dir(&directory_clone)
            //     .spawn()
            //     .expect("Failed to execute cargo test");
            // let mut buf = String::new();
            // let stdout = command
            // .stdout
            // .as_mut();
            // if let Some(stdout) = stdout {
            //     if let Ok(r) = stdout.read_to_string(&mut buf) {
            //         println!("cargo check 执行完毕: {}", buf);
            //     }
            // }
            // let p = format!("{}{}", &prompt_test_clone.test.unwrap(), "\n请根据cargo test的输出，优化代码, 请不要输出cargo test的输出， 以下是cargo test的输出：".to_string() + &buf);
            // let test_result = chat(&p, Some(&mut c_2_rust_glm), model.clone(), name_clone.clone()).await;
            // // let test_result = chat(t, Some(&mut c_2_rust_glm), model.clone(), name_clone.clone()).await;
            // test_result
        })
        .await
        .unwrap();
        test.write_all(remove_markdown_code_block(&test_result).as_bytes())
            .expect("Failed to write to file");
    }
}



pub async fn translate_prompt_project(
    name: String,
    c_2_rust_glm: &mut C2RustGLM,
    prompt: String,
    model: BigModel,
) -> String {
    let output_dir = format!("./Output/{}", name);
    println!("output_dir: {}", output_dir);
    // 如果目录不存在则创建
    if !Path::new(&output_dir).exists() {
        fs::create_dir_all(&output_dir).expect("Failed to create directory");
    }
    println!("start call chat function prompt {:?}", &prompt[..std::cmp::min(prompt.len(), 1000)]);
    let output = chat(&prompt, Some(c_2_rust_glm), model, name).await;
    println!("=========================================\n=====================translate_prompt_project output: \n{}", output);
    let lines = output.lines().collect::<Vec<&str>>();
    let mut ret = String::new();
    let mut flag = false;
    let mut file_name = String::new();
    let mut is_toml = false;
    for line in lines {
        println!("line: {}", line);
        if line.contains("```markdown") {
            continue;
        }
        if line.contains("## Usage") {
            break;
        }
        if line.contains("## ") && (line.contains(".rs") || line.contains(".toml")) {
            file_name = line.split("## ").collect::<Vec<&str>>()[1].to_string();
            // 如果文件不存在则创建
            let file_path = format!("{}/{}", output_dir, file_name);
            println!("====file_name: {}", file_name);
            println!("====file_path: {}", file_path);
            // 获取文件的目录
            let file_dir = file_path.split("/").collect::<Vec<&str>>()[0..file_path.split("/").count() - 1].join("/");
            if !Path::new(&file_dir).exists() {
                fs::create_dir_all(&file_dir).expect("Failed to create directory");
            }
            if !Path::new(&file_path).exists() {
                File::create(&file_path).expect("Failed to create file");
            }
            flag = false;
            continue;
        }
        if line.contains("```rust") || line.contains("```toml") {
            if line.contains("toml") {
                is_toml = true;
            }
            flag = true;
            continue;
        }
        if line.contains("```") && flag == true {
            flag = false;
            // 将内容写入文件, 如果文件不存在则创建
            let file_path = format!("{}/{}", output_dir, file_name);
            println!("file_name: {}", file_name);
            println!("file_path: {}", file_path);
            let file_dir = file_path.split("/").collect::<Vec<&str>>()[0..file_path.split("/").count() - 1].join("/");
            if !Path::new(&file_dir).exists() {
                fs::create_dir_all(&file_dir).expect("Failed to create directory");
            }
            if !Path::new(&file_path).exists() {
                File::create(&file_path).expect("Failed to create file");
            }
            fs::write(file_path, ret).expect("Failed to write to file");
            ret = String::new();
            is_toml = false;
            continue;
        }
        if flag {
            // println!("flag: {}, line: {}", flag, line);
            if is_toml == true && line.contains("=") && !line.contains("\"") {
                let key_value: Vec<&str> = line.split("=").collect();
                let key = key_value[0].trim();
                let value = key_value[1].trim();
                ret.push_str(&format!("{} = \"{}\"\n", key, value));
            } else {
                ret.push_str(&format!("{}\n", line));
            }
        }
    }
    output
}



pub fn traverse_dir(
    dir_path: &str,
    test_path: &str,
    filenames: Vec<String>,
    header_files: &mut HashMap<String, String>,
    source_files: &mut HashMap<String, String>,
    test_files: &mut HashMap<String, String>,
    tmp_src_dir: &str,
    tmp_test_dir: &str,
) -> std::io::Result<()> {

    let mut project_deps: HashMap<String, Vec<String>> = HashMap::new();
    let input_dir = "./Input/02-Primary";
    let input_src_dir = "./Input/02-Primary/src";
    let input_test_dir = "./Input/02-Primary/test";
    let input_files = fs::read_dir(input_src_dir)?;

    for file in input_files {
        let file = file?;
        let file_path = file.path();
        if file_path.is_file() {
            let file_name = file_path.file_stem().unwrap().to_str().unwrap().to_string();
            if filenames.contains(&file_name) && file_path.extension().unwrap() == "c" {
                let content = fs::read_to_string(&file_path)?;
                let mut dependencies = Vec::new();
                for line in content.lines() {
                    if line.starts_with("#include") {
                        if let Some(dep) = line.split_whitespace().nth(1) {
                            let dep = dep.replace("\"", "")
                                .replace("<", "")
                                .replace(">", "");
                            dependencies.push(dep);
                        }
                    }
                }
                project_deps.insert(file_name, dependencies);
                // println!("project_deps: {:?}", project_deps);
            }
        }
    }

    println!("project_deps: {:?}", project_deps);

    let dir = fs::read_dir(dir_path)?;
    let mut tmp_src_dir = tmp_src_dir.to_string();
    let mut tmp_test_dir = tmp_test_dir.to_string();
    for entry in dir {
        let entry = entry?;
        let path = entry.path();
        if path.is_file() {
            let filename = path.file_stem().unwrap().to_str().unwrap().to_string();
            if !filenames.contains(&filename) {
                continue;
            }
            // 将源文件复制到tmp目录中
            let tmp_src_path = format!("{}/{}", tmp_src_dir, path.file_name().unwrap().to_string_lossy());
            fs::copy(&path, &tmp_src_path).expect("Failed to copy source file");

            // 根据project_deps中的依赖关系，将依赖的文件复制到tmp目录中
            if let Some(deps) = project_deps.get(&filename) {
                for dep in deps {
                    // 检查依赖的文件在input_dir的哪个目录下就复制到Tmp的对应目录下
                    let _dep_path = format!("{}/{}", input_dir, dep);
                    let dep_src_path = format!("{}/{}", input_src_dir, dep);
                    let dep_test_path = format!("{}/{}", input_test_dir, dep);
                    let tmp_src_path = format!("{}/{}", tmp_src_dir, dep);
                    let tmp_test_path = format!("{}/{}", tmp_test_dir, dep);
                    // if Path::new(&dep_path).exists() {
                    //     fs::copy(dep_path, &tmp_src_path).expect("Failed to copy dependency file");
                    // } else 
                    if Path::new(&dep_src_path).exists() {
                        fs::copy(dep_src_path, &tmp_src_path).expect("Failed to copy dependency file");
                    } else if Path::new(&dep_test_path).exists() {
                        fs::copy(dep_test_path, &tmp_test_path).expect("Failed to copy dependency file");
                    }
                }
            }

            //println!("File name:{:?}",path.file_name().unwrap());
            if let Some(extension) = path.extension() {
                if extension == "h" {
                    // 读取头文件内容
                    if let Ok(content) = fs::read_to_string(&path) {
                        let filename = path.file_stem().unwrap().to_str().unwrap().to_string();
                        header_files.insert(filename.clone(), content);
                    }
                } else if extension == "c" {
                    // 读取C源文件内容
                    if let Ok(content) = fs::read_to_string(&path) {
                        let filename = path.file_stem().unwrap().to_str().unwrap().to_string();
                        source_files.insert(filename.clone(), content);
                    }
                }
            }
        } else if path.is_dir() {
            // 将源目录复制到tmp目录中的对应子目录中
            let tmp_src_path = format!("{}/{}", tmp_src_dir, path.file_name().unwrap().to_string_lossy());
            fs::copy(&path, &tmp_src_path).expect("Failed to copy source directory");
            tmp_src_dir = tmp_src_path;
            let _ = traverse_dir(
                &path.to_string_lossy(),
                test_path,
                filenames.clone(),
                header_files,
                source_files,
                test_files,
                &tmp_src_dir,
                &tmp_test_dir,
            )
            .unwrap();
        }
    }

    let test_dir = fs::read_dir(test_path)?;
    let _test_names = filenames
        .iter()
        .map(|it| format!("test-{}", it))
        .collect::<Vec<String>>();
    for entry in test_dir {
        let entry = entry?;
        let path = entry.path();
        if path.is_file() {
            let filename = path.file_stem().unwrap().to_str().unwrap().to_string();
            if !filenames.contains(&filename) {
                continue;
            }
            // 将test文件复制到tmp目录中
            let tmp_test_path = format!("{}/{}", tmp_test_dir, path.file_name().unwrap().to_string_lossy());
            fs::copy(&path, &tmp_test_path).expect("Failed to copy test file");
            if let Some(deps) = project_deps.get(&filename) {
                for dep in deps {
                    // 检查依赖的文件在input_dir的哪个目录下就复制到Tmp的对应目录下
                    let _dep_path = format!("{}/{}", input_dir, dep);
                    let dep_src_path = format!("{}/{}", input_src_dir, dep);
                    let dep_test_path = format!("{}/{}", input_test_dir, dep);
                    let tmp_src_path = format!("{}/{}", tmp_src_dir, dep);
                    let tmp_test_path = format!("{}/{}", tmp_test_dir, dep);
                    // if Path::new(&dep_path).exists() {
                    //     fs::copy(dep_path, &tmp_src_path).expect("Failed to copy dependency file");
                    // } else 
                    if Path::new(&dep_src_path).exists() {
                        fs::copy(dep_src_path, &tmp_src_path).expect("Failed to copy dependency file");
                    } else if Path::new(&dep_test_path).exists() {
                        fs::copy(dep_test_path, &tmp_test_path).expect("Failed to copy dependency file");
                    }
                }
            }
            //println!("File name:{:?}",path.file_name().unwrap());
            if let Ok(content) = fs::read_to_string(&path) {
                test_files.insert(filename.clone(), content);
            }
        } else if path.is_dir() {
            // 将test目录复制到tmp目录中
            let tmp_test_path = format!("{}/{}", tmp_test_dir, path.file_name().unwrap().to_string_lossy());
            fs::copy(&path, &tmp_test_path).expect("Failed to copy test directory");
            tmp_test_dir = tmp_test_path;
            let _ = traverse_dir(
                &path.to_string_lossy(),
                test_path,
                filenames.clone(),
                header_files,
                source_files,
                test_files,
                &tmp_src_dir,
                &tmp_test_dir,
            )
            .unwrap();
        }
    }

    Ok(())
}



// 解析单目录多项目类文件
pub fn translate_prompt_sign_dir_mti_project(base_dir: &str, filenames: Vec<String>) -> Vec<CodeFile> {
    let mut ret = Vec::<CodeFile>::new();
    // 指定目录
    let binding = ["./Input/", &base_dir, "/src"].concat();
    let src_directory: &str = binding.as_str();
    let binding1 = ["./Input/", &base_dir, "/test"].concat();
    let test_directory: &str = binding1.as_str();

    let _base_dir = ["./Input/", &base_dir].concat();

    // let rendered = codes2prompts(&base_dir).unwrap();
    // println!("函数接受回来的数据： rendered: {}", rendered);

    // 读取目录中的所有文件
    let mut header_files = HashMap::new();
    let mut source_files = HashMap::new();
    let mut test_files = HashMap::new();

    for filen in filenames {
        let tmp_dir = format!("./Tmp/{}", filen);
        let tmp_src_dir = format!("{}/src", tmp_dir);
        let tmp_test_dir = format!("{}/test", tmp_dir);

        // 创建目录
        if !Path::new(&tmp_dir).exists() {
            fs::create_dir_all(&tmp_src_dir).expect("Failed to create src directory");
            fs::create_dir_all(&tmp_test_dir).expect("Failed to create test directory");
        }

        // 复制文件到新建的项目中
        let _ = traverse_dir(
            src_directory,
            test_directory,
            vec![filen.clone()],
            &mut header_files,
            &mut source_files,
            &mut test_files,
            &tmp_src_dir,
            &tmp_test_dir
        )
        .unwrap();   

        // 根据tmp目录中的文件生成prompt
        let project_prompt = codes2prompts(&tmp_dir).unwrap();
        // println!("project_prompt: {}", project_prompt);
        println!("project_prompt_output 已经生成");
        ret.push(CodeFile {
            filename: filen.clone(),
            content: project_prompt,
            test: None,
        });
    }
    ret

    // 处理文件对
    // for (filename, header_content) in &header_files {
    //     if let Some(source_content) = source_files.get(filename) {
    //         // 生成转译代码的prompt
    //         let mut test_prompt = None;
    //         if let Some(c) = test_files.get(format!("test-{}", filename).as_str()) {
    //             let rust_filename = filename.clone().replace(".c", "rs");
    //             let prompt = format!("Translate the following C code to Rust, Output only the code content, do not need to output the comment content; code is {}; This should be a main.rs file content and import the public function in this file,it's filename is : {}, the generated code on last step and the current source code is: {}, ", c, rust_filename, source_content);
    //             test_prompt = Some(prompt);
    //         }
    //         let prompt = format!("Translate the following C code to Rust; Output only the code content, do not need to output the comment content; and do not need output the main function in the code but need to public the function; this is head file content: {} \n and this is source file content: {}, ", header_content, source_content);
    //         ret.push(CodeFile {
    //             filename: filename.clone(),
    //             content: prompt,
    //             test: test_prompt,
    //         });
    //     }
    // }
    // ret
}



// 写一个遍历目录树获取指定文件名的函数，可能需要递归
pub fn traverse_dir_get_file_name(dir: &str, file_name: &str) -> Vec<String> {
    let mut ret = Vec::<String>::new();
    if let Ok(entries) = fs::read_dir(dir) {
        for entry in entries {
            if let Ok(entry) = entry {
                let path = entry.path();
                if path.is_file() {
                    if let Some(name) = path.file_name() {
                        if name.to_string_lossy().to_string() == file_name {
                            ret.push(name.to_string_lossy().to_string());
                        }
                    }
                } else if path.is_dir() {
                    // Recursively traverse subdirectories
                    let subdir_files = traverse_dir_get_file_name(
                        path.to_str().unwrap_or(""),
                        file_name
                    );
                    ret.extend(subdir_files);
                }
            }
        }
    }
    ret
}

// 根据输入目录和主文件名，将项目转为但目录项目
pub fn translate_project_to_single_dir(base_dir: &str, main_file: &str) -> Result<TranscodeParams, String> {
    let mut c_result = TranscodeParams {
        project_name: base_dir.to_string(),
        content: vec![],
    };
    // 获取当前项目的根路径
    let _root_dir = std::env::current_dir().unwrap();
    // println!("============================================root_dir: {}", root_dir.to_string_lossy());
    // 根据main_file 和 base_dir 找到主函数
    let main_file_path = format!("{}/{}/{}", "./Input", base_dir, main_file);
    // println!("============================================main_file_path: {}", main_file_path);
    let main_file_name = Path::new(&main_file_path).file_name().unwrap().to_string_lossy().to_string();
    // println!("============================================main_file_name: {}", main_file_name);
    let main_file_content = fs::read_to_string(&main_file_path).unwrap();
    // println!("============================================main_file_content: {}", main_file_content);
    let main_function = main_file_content.lines().find(|line| line.contains("main") && !line.starts_with("//"));
    if main_function.is_none() {
        // return Err(format!("Main function not found in {}", main_file_path));
        return Err(format!("Main function not found in {}", &main_file_path));
    }

    // 重写C主函数文件内容
    let mut main_content = String::from("\n");
    // 循环遍历main_file_content 找到所有依赖的文件
    for line in main_file_content.lines() {
        if line.contains("#include") {
            let dep = line.split_whitespace().nth(1).unwrap().replace("\"", "").replace("<", "").replace(">", "");
            let dep_files = traverse_dir_get_file_name(format!("{}/{}", "./Input", base_dir).as_str(), dep.as_str());
            if dep_files.len() > 0 {
                let curr_line = format!("{}\n", line).replace("<", "\"").replace(">", "\"");
                main_content.push_str(curr_line.as_str());
            } else {
                main_content.push_str(format!("{}\n", line).as_str());
            }
        } else {
            main_content.push_str(format!("{}\n", line).as_str());
        }
    }
    // 将主函数内容填入到c_result中
    c_result.content.push(TranscodePathParams {
        path: main_file_name.replace(".c", ".c").replace(".cpp", ".c"),
        code: main_content,
    });

    // 递归遍历base_dir下所有文件写入到并将内容写入c_result中，其中要判断非主函数文件是否函数main 函数，如果函数则忽略不用写
    let _ = traverse_dir_write_file(format!("{}/{}", "./Input", base_dir).as_str(), &mut c_result);

    Ok(c_result)
}

// 写一个递归遍历函数 遍历base_dir下所有文件写入到并将内容写入c_result中，其中要判断非主函数文件是否函数main 函数，如果函数则忽略不用写
pub fn traverse_dir_write_file(dir: &str, c_result: &mut TranscodeParams) -> Result<(), String> {
    let dir = fs::read_dir(dir).map_err(|e| e.to_string())?;
    for entry in dir {
        let entry = entry.map_err(|e| e.to_string())?;
        let path = entry.path();
        
        if path.is_dir() {
            traverse_dir_write_file(path.to_str().unwrap(), c_result)?;
        } else if path.is_file() {
            let file_name = path.file_name().unwrap().to_string_lossy().to_string();
            // Skip non C/C++ files
            // if !file_name.ends_with(".c") && !file_name.ends_with(".cpp") {
            //     continue;
            // }
            
            let file_content = fs::read_to_string(&path).map_err(|e| e.to_string())?;
            
            // Skip files containing main function unless it's the designated main file
            if !file_name.contains("main") && file_content.contains("main(") {
                continue;
            }

            let mut content = String::from("\n");
            for line in file_content.lines() {
                content.push_str(format!("{}\n", line).as_str());
            }

            c_result.content.push(TranscodePathParams {
                path: path.file_name().unwrap().to_string_lossy().to_string(),
                code: content,
            });
        }
    }
    Ok(())
}

pub async fn translate_c_project_with_c2rust(base_dir: &str, _main_file: &str, trans_codes: TranscodeParams) {
    let result = chat_c2rust(&trans_codes).await;
    // println!("result: {:?}", result);
    // 将result 写入文件
    let mut file = File::create("c2rust_result.json").unwrap();
    file.write_all(serde_json::to_string(&result).unwrap().as_bytes()).unwrap();
    match result {
        Ok(result) => {
            // 根据result 和 base_dir 和 main_file 递归生成目录和文件
            let p_n = format!("{}/{}", "./Output", base_dir);
            let _ = fs::create_dir_all(&p_n);
            result.content.iter().for_each(|it| {
                // 根据it.path提取目录和文件名
                let mut path = it.path.split("/").collect::<Vec<&str>>();
                let _file_name = path.pop().unwrap();
                let dir = path.join("/");
                // 如果目录不存在则创建目录
                let dir_path = format!("{}/{}", p_n, dir);
                if !Path::new(&dir_path).exists() {
                    let _ = fs::create_dir_all(dir_path);
                }
                let _ = fs::write(format!("{}/{}", p_n, it.path), it.code.clone());
            });
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }
}


pub const TRANSLATE_PROJECT_CONTENT: &str = r#"
```markdown
# Project: `add`

## Cargo.toml

```toml
[package]
name = "add"
version = "0.1.0"
edition = "2021"

[dependencies]

[[tests]]
name = test_add
path = "tests/test-add.rs"
```

## Source Tree

```
add/
├── src
│   └── add.rs
└── tests
    └── test-add.rs
```

## src/add.rs

```rust
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
```

## tests/test-add.rs

```rust
use add::add;

#[test]
fn test_add() {
    let num1 = 10;
    let num2 = 20;
    let result = add(num1, num2);
    assert_eq!(result, 30);
}
```
"#;
